<?php


namespace Api\Http\Controllers;


use Api\Jobs\AddPostmanInfo;
use Api\Jobs\MemberProfitTask;
use Api\Jobs\YidaPushTask;
use Api\Service\YidaService;
use Api\Service\YunyangService;
use Api\traits\ApiResponse;
use Carbon\Carbon;
use Catch\Traits\DB\BaseOperate;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use Illuminate\Http\Request;
use Api\Http\Controllers\Controller;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Log as Logs;
use Illuminate\Support\Facades\Redis;
use EasyWeChat\MiniApp\Application;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Modules\Express\Models\ExpressPlatform;
use Modules\Express\Models\Yida;
use Modules\Member\Models\Members;
use Modules\Member\Models\MembersPriceLog;
use Modules\Member\Models\MembersProfit;
use Modules\Order\Models\Orders;
use Modules\Express\Models\ExpressChannel;
use Modules\Order\Models\RefundRecord;
use Modules\Shop\Models\Coupon;
use Modules\Shop\Models\Pivots\UserHasCoupons;
use Modules\Shop\Models\Pivots\UserHasCoupons as MemberCoupon;
use Overtrue\Pinyin\Pinyin;


/**
 * @group 用户模块
 *
 * @subgroup 用户管理
 * @subgroupDescription CatchAdmin 后台用户管理
 *
 */
class OrderController extends Controller
{
    use ApiResponse;

    public function __construct(
        protected readonly Orders       $order,
        protected readonly MemberCoupon $memberCoupon,
    )
    {

    }

    /**
     *订单列表
     *
     * @queryParam department_id int 部门
     * @queryParam page int 页码
     * @queryParam limit int 每页条数
     * @queryParam Membername string 关键字
     * @queryParam email string 邮箱
     * @queryParam status int 状态
     *
     */
    public function index(Request $request)
    {
        $status = $request->input('status');
        $where = [];
        if (!is_null($status)) {
            $where[] = ['status', '=', $status];
        }
        $limit = $request->input('limit', 10);
        $list = $this->order::where('user_id', $this->getLoginUserId())->where($where)->orderBy('id', 'desc')->paginate($limit);
        return $this->data($list->toArray());
    }

    /**
     * 检测渠道
     *
     * @bodyParam Membername string required 用户名
     * @bodyParam password string required 密码
     * @bodyParam email string 邮箱
     * @bodyParam mobile string 手机号
     * @bodyParam department_id int 部门
     * @bodyParam roles integer[] 角色
     * @bodyParam jobs integer[] 职位
     *
     * @responseField data int 新增ID
     *
     * @return false|mixed
     * @throws InvalidArgumentException
     */
    public function checkChannel(Request $request)
    {
        $data = $request->all();
        if (empty($data['senderCounty']) || empty($data['receiveCounty'])) {
            return $this->fail('请删除当前地址并手动选择省市区下单');
        }

        //云洋
        $json = (new YunyangService)->checkChannel($data);
        $result = json_decode($json, true);
        $userLevel = Members::where('id', $this->getLoginUserId())->value('user_level');
        if ($result['code'] != 1) {
            return $this->fail('渠道不可用');
        }

        $result = $result['result'];
        $tagArr = [];
        foreach ($result as $k => &$v) {
            if ($request->post('channelTag') == '重货' && $v['tagCode'] != 2) {
                unset($result[$k]);
                continue;
            }
            $tagType = $v['tagType'];
            if (in_array($tagType, $tagArr)) {
                unset($result[$k]);
                continue;
            }
            $v['channelType'] = 'yunyang';
            $tagCode = $v['tagCode'];
            $config = ExpressPlatform::where('express_code', $tagCode)
                ->where('type', $request->post('channelTag'))
                ->first();
            if (empty($config)) {
                return $this->fail('渠道不可用');
            }
            $weight = round($request->post('weight'));
            if ($v['chargeType'] == 1) {
                $v['priceOne'] = bcadd((string)$config['price_one'], $v['discountPriceOne'], 2);
                $v['priceMore'] = bcadd((string)$config['price_more'], $v['discountPriceMore'], 2);

            } else {
                $v['priceOne'] = bcadd((string)$config['price_one'], (string)$v['priceOne'], 2);
                $v['priceMore'] = bcadd((string)$config['price_more'], (string)$v['priceMore'], 2);
            }
            if (!empty($v['originalPrice'])) {
                $originalPrice1 = bcadd((string)$config['price_one'], $v['originalPrice'], 2);
                $originalPrice2 = bcadd($originalPrice1, (string)((ceil($weight) - 1) * $v['priceMore']), 2);
                $v['originalPrice'] = $originalPrice2;
            }

            if ($weight <= 1) {
                $v['realPrice'] = $v['priceOne'];
            } else {
                $v['realPrice'] = bcadd($v['priceOne'], (string)((ceil($weight) - 1) * $v['priceMore']), 2);
            }

            Redis::setex($this->getLoginUserId() . "_" . $data['senderCounty'] . $data['senderLocation'] . $data['receiveCounty'] . $data['receiveLocation'] . "_" . $v['channelId'], 1800, $v['realPrice']);
            $tagArr[] = $v['tagType'];
        }

        //云洋结束
        //易达
        $yidaList = $this->yidaCheckChannel($data);
        if (empty($yidaList)) {
            $priceArr = array_column($result, 'realPrice');
            array_multisort($priceArr, SORT_ASC, $result);
            return $this->data($result);
        } else {
            $baojiaArr = [1, 2, 6]; //保价渠道顺丰德邦和京东只选择云洋
            $list = [];
            foreach ($result as $k => $yunyang) {
                $tagCode = $yunyang['tagCode'];
                $totalFreight = $yunyang['totalFreight'];
                foreach ($yidaList as $kk => $yida) {
                    //快递公司相同
                    if ($yida['tagCode'] == $tagCode) {
                        if ($totalFreight <= $yida['totalFreight'] || in_array($tagCode, $baojiaArr)) {
                            $list[] = $yunyang;
                        } else {
                            $yida['channelLogoUrl'] = $yunyang['channelLogoUrl'];
                            $list[] = $yida;
                        }
                        unset($yidaList[$kk]);
                    }
                }

            }
            if (!empty($yidaListi)) {
                $list = array_merge($list, $yidaListi);
            }

            if (!empty($list)) {
                $priceArr = array_column($list, 'realPrice');
                array_multisort($priceArr, SORT_ASC, $list);
                return $this->data($list);
            } else {
                return $this->fail('暂无匹配渠道');
            }
        }


    }

    private function yidaCheckChannel($data)
    {
        $service = new YidaService();
        $result = $service->checkChannel($data);
        $insure = $data['insured'] ?? 0;
        $channelTag = $data['channelTag'];
        $temp = [];
        if (empty($result)) {
            return [];
        }
        foreach ($result as $k => $v) {

            if (current($v)) {
                $temp[] = current($v);
            }
        }
        $list = [];
        foreach ($temp as $item) {

            $temp2 = [];
            $channelId = $item['channelId'];
            $temp2['channelId'] = $channelId;
            $typeStr = $item['deliveryType'];
            $feeTpe = $item['calcFeeType'];
            $expressInfo = ExpressPlatform::where('express_str', $typeStr)->where('type', $channelTag)->first();
            $temp2['tagType'] = $expressInfo['express_name'];
            $temp2['tagCode'] = $expressInfo['express_code'];
            $temp2['totalFreight'] = $item['preOrderFee'];
            if ($data['channelTag'] == '重货' && $expressInfo['express_code'] != 2) {
                continue;
            }

            if ($feeTpe == 'profit') {
                $priceInfo = json_decode($item['price'], true);
                $current = current($priceInfo);
                $first = $current['first'];
                $add = $current['add'];
                $priceMore = $temp2['priceMore'] = bcadd((string)$add, (string)$expressInfo->yida_price_more, 2);
                $priceOne = $temp2['priceOne'] = bcadd((string)$first, (string)$expressInfo->yida_price_one, 2);
            } else {
                $priceInfo = json_decode($item['price'], true);   //折扣
                $originalPrice = json_decode($item['originalPrice'], true); //原价
                $current = current($originalPrice);
                $first = $current['first'];
                $add = $current['add'];
                $discount = $priceInfo['discount'];
                $priceOne = $temp2['priceOne'] = bcadd((string)($first * $discount), (string)$expressInfo->yida_price_one, 2);
                $priceMore = $temp2['priceMore'] = bcadd((string)($add * $discount), (string)$expressInfo->yida_price_more, 2);
            }
            $weight = round($data['weight']);
            if ($weight <= 1) {
                $realPrice = $priceOne;
                $temp2['originalPrice'] = bcadd((string)$item['preOrderFee'], (string)$expressInfo->yida_price_one, 2);
            } else {
                $realPrice = bcadd($priceOne, (string)((ceil($weight) - 1) * $priceMore), 2);
                $originalPrice1 = bcadd((string)$item['preOrderFee'], (string)$expressInfo->yida_price_one, 2);
                $originalPrice2 = bcadd($originalPrice1, (string)((ceil($weight) - 1) * (string)$expressInfo->yida_price_more), 2);
                $temp2['originalPrice'] = $originalPrice2;
            }
            $temp2['realPrice'] = $realPrice;
            $temp2['originalPrice'] = bcadd($temp2['originalPrice'], $insure, 2);
            if (empty($item['bjRule'])) {
                $temp2['allowInsured'] = 0;
                $temp2['insuredRate'] = '';
            } else {
                $temp2['allowInsured'] = 0;
                $ruleList = json_decode($item['bjRule'], true);
                $temp2['insuredRate'] = '';
                foreach ($ruleList as $rule) {
                    if (isset($rule['bjRate'])) $temp2['insuredRate'] = $rule['bjRate'];
                }
            }

            $temp2['channelType'] = 'yida';
            $temp2['paozhong'] = $item['lightGoods'];
            Redis::setex($this->getLoginUserId() . "_" . $data['senderCounty'] . $data['senderLocation'] . $data['receiveCounty'] . $data['receiveLocation'] . "_" . $channelId, 1800, $realPrice);
            $list[] = $temp2;
        }

        return $list;
    }


    //创建订单
    public function store(Request $request)
    {
        //超重订单未补款无法继续下单
        $overCount = Orders::where('is_overweight', 1)->where('overweight_paid_at', '0')->where('user_id', $this->getLoginUserId())->count();
        if ($overCount > 0) {
            return $this->fail('超重订单未补款,无法下单');
        }
        $haocaiCount = Orders::where('is_haocai', 1)->where('haocai_paid_at', '0')->where('user_id', $this->getLoginUserId())->count();
        if ($haocaiCount > 0) {
            return $this->fail('耗材订单未补款,无法下单');
        }
        $data = $request->all();
        if (mb_strlen($data['receiver'], "UTF-8") > 20) {
            return $this->fail('收件人长度不能超过20个汉字');
        }
        if (mb_strlen($data['sender'], "UTF-8") > 20) {
            return $this->fail('发件人长度不能超过20个汉字');
        }
        $price = Redis::get($this->getLoginUserId() . "_" . $data['senderCounty'] . $data['senderLocation'] . $data['receiveCounty'] . $data['receiveLocation'] . "_" . $data['channelId']);
        if (empty($price)) {
            return $this->fail('订单超时');
        }
        if (!empty($data['coupon_id'])) {
            //如果使用优惠券
            $this->order->coupon_id = $data['coupon_id'];
            $couponInfo = Coupon::find($data['coupon_id']);
            if ($couponInfo->type == 2 && $this->getLoginUser()->user_level > 0) {
                return $this->fail('代理不能使用抢购优惠券');
            }
            //新人优惠券重复使用
            if ($couponInfo->type == 1) {
                $useRecord = UserHasCoupons::where('coupon_id', $couponInfo->id)->where('status', 1)->where('user_id', $this->getLoginUserId())->first();
                if ($useRecord) {
                    return $this->fail('优惠券重复使用,请重新下单');
                }
            }
            $reduce = $couponInfo->reduce_price;
            $this->order->reduce_price = $reduce;
            $price = bcsub((string)$price, (string)$reduce, 2);

        }
        if ($this->getLoginUser()->user_level > 0) {
            $price = bcsub($price, '0.7', 2);
        }
        $this->order->platform_id = $data['tagCode'] ?? 3;  //快递平台标识
        if ($data['channelType'] == 'yida') {
            $expressInfo = ExpressPlatform::where('express_code', $data['tagCode'])->where('type', $data['channelTag'])->first();
            $this->order->tag_str = $expressInfo->express_str;
        }

        $this->order->channel_type = $data['channelType'];  //快递渠道名称
        $this->order->channel_tag = $data['channelTag'];  //快递中文名称
        $this->order->channel_id = $data['channelId'];  //快递中文名称
        $this->order->tag_type = $data['tag_type'];  //快递中文名称
        $this->order->channel_logo_url = $data['channel_logo_url'];  //快递logo
        $this->order->order_sn = "k" . date("Ymd") . uniqid();
        $this->order->sender = $data['sender'];
        $this->order->sender_mobile = $data['senderMobile'];
        $this->order->sender_province = $data['senderProvince'];
        $this->order->sender_city = $data['senderCity'];
        $this->order->sender_county = $data['senderCounty'];
        $this->order->receive_town = $data['receiveTown'];
        $this->order->sender_location = $data['senderLocation'];
        $this->order->sender_address = $data['senderAddress'];
        $this->order->receiver = $data['receiver'];
        $this->order->receiver_mobile = $data['receiverMobile'];
        $this->order->receive_province = $data['receiveProvince'];
        $this->order->receive_city = $data['receiveCity'];
        $this->order->sender_town = $data['senderTown'];
        $this->order->receive_county = $data['receiveCounty'];
        $this->order->receive_location = $data['receiveLocation'];
        $this->order->receive_address = $data['receiveAddress'];
        $this->order->weight = $data['weight'];
        $this->order->vloum_long = $data['vloumLong'] ?? 0;
        $this->order->vloum_width = $data['vloumWidth'] ?? 0;
        $this->order->vloum_height = $data['vloumHeight'] ?? 0;
        $this->order->type = '待付款';
        $this->order->item_name = $data['itemName']; //物品名称
        $this->order->package_count = $data['packageCount'];  //包裹数量
        $this->order->bill_remark = $data['billRemark']; //订单备注
        $this->order->price_one = $data['priceOne'] ?? null; //首重
        $this->order->price_more = $data['priceMore'] ?? null; //续重
        if (!is_null($data['insured'])) {
            $this->order->insured = $data['insured'];
            $this->order->money = bcadd($price, (string)$data['insured'], 2); //应付款价格 (包含保价费)
        } else {
            $this->order->money = $price;
        }

        $this->order->real_price = bcadd($data['real_price'], (string)$data['insured'], 2); //原价
        $this->order->user_id = $this->getLoginUserId();

        if ($this->order->save()) {
            $flag = false;
            if (!empty($data['coupon_id'])) {
                //更新优惠券状态
                $this->memberCoupon->where('user_id', $this->getLoginUserId())->where('coupon_id', $data['coupon_id'])->update(['status' => 1]);
            }
            $orderInfo = $this->order->fresh();
            $orderInfo->platform_id = $data['tagCode'];
            $orderInfo->save();

            //用户下单数量+1
            Members::where('id', $orderInfo->user_id)->increment('over_count');

            //返佣以及记录
//            $userId = $orderInfo->user_id;
//            if (!empty($orderInfo->coupon_id)) {
//                $useCoupon = true;
//            } else {
//                $useCoupon = false;
//            }
//            //首重续重分销计算
//            $push['orderId'] = $orderInfo->id;
//            $push['userId'] = $orderInfo->user_id;
//            $push['useCoupon'] = $useCoupon;
//            $push['first'] = true;
//            if ($orderInfo->weight > 1) {
//                $push['more'] = true;
//                $push['calWeight'] = bcsub((string)$orderInfo->weight, '1');
//            }
//            $push['platform'] = $data['tagCode'];
//            MemberProfitTask::dispatch($push);

            return $this->data($this->order->fresh()->toArray());
        } else {
            return $this->fall('创建失败');
        }
    }

    /**
     * @param Request $request
     * @return Response
     * 取消订单
     */
    public function cancelOrder(Request $request)
    {
        $data = $request->all();
        $orderInfo = $this->order->where('waybill', $data['waybill'])->first();
        if (empty($orderInfo)) {
            return $this->success('取消成功');
        }
        $time = time();
        $wechat = new WechatController();
        //未支付订单
        if (empty($orderInfo->paid_at)) {
            Log::info(json_encode($orderInfo->toArray()));
            //未付款手动取消
            $orderInfo->type = '已取消';
            $orderInfo->type_code = 99;
            $orderInfo->status = 2;
            $orderInfo->save();
            return $this->success('取消成功');
        }
        //30分钟内已支付待揽收的可以取消
        if ($orderInfo->paid_at > $time - 1800 && $orderInfo->type_code == 1) {

            $couponId = $orderInfo->coupon_id;
            // 退款退还优惠券
            if (!empty($couponId)) {
                UserHasCoupons::where('user_id', $this->getLoginUserId())->where('coupon_id', $couponId)->update(['status' => 0]);
            }
            //云洋取消订单
            try {
                if ($orderInfo->channel_type == 'yida') {
                    $json = (new YidaService)->cancelOrder($data);
                    $result = json_decode($json, true);
                    if ($result['code'] == 200) {
                        $orderInfo->cancel_remark = $data['cancel_remark'] ?? '';
                        $orderInfo->type = '已退款';
                        $orderInfo->status = 2;
                        $orderInfo->type_code = 5;
                        $orderInfo->save();
                        $wechat->refundOrder($orderInfo->order_sn, $orderInfo->money);
                        return $this->success('取消成功');
                    } else {
                        return $this->fail($result['message']);
                    }
                } else {
                    $json = (new YunyangService)->cancelOrder($data);
                    $result = json_decode($json, true);
                    if ($result['code'] == 1) {
                        $orderInfo->cancel_remark = $data['cancel_remark'] ?? '';
                        $orderInfo->type = '已退款';
                        $orderInfo->status = 2;
                        $orderInfo->type_code = 5;
                        $orderInfo->save();
                        $wechat->refundOrder($orderInfo->order_sn, $orderInfo->money);
                        return $this->success('取消成功');
                    } else {
                        return $this->fail($result['message']);
                    }
                }

            } catch (\Exception $e) {
                return $this->fail('订单异常,请联系客服解决');
            }


        }
        return $this->fail('订单超时请联系客服解决');
    }

    public function show($id)
    {
        $info = $this->order->find($id);
        return $this->data($info->toArray());
    }

    /**
     * @param Request $request
     * @return Response
     *云洋回调接口
     * @throws InvalidArgumentException
     */
    public function callback(Request $request)
    {
        $result = $request->post();
        $orderInfo = $this->order->where('waybill', $result['waybill'])->first();
        $userInfo = Members::find($orderInfo->user_id);
        $config = ExpressPlatform::where('express_code', $orderInfo->platform_id)->where('type', $orderInfo->channel_tag)->first();
        $wechat = new WechatController();
        if (!empty($result['courierName'])) {
            $orderInfo->postman_name = $result['courierName'];
        }
        if (!empty($result['courierPhone'])) {
            $orderInfo->postman_mobile = $result['courierPhone'];
        }


        //耗材费判断
        $orderHaocai = $orderInfo->haocai_money;
        $realHaocai = $result['freightHaocai'] ?? '';
        //如果推送价格大于订单的耗材费(默认为0元)
        if ($realHaocai > $orderHaocai && ($orderInfo->is_haocai == 0)) {
            $orderInfo->is_haocai = 1;
            $orderInfo->haocai_sn = uniqid();
            $orderInfo->haocai_money = bcsub((string)$realHaocai, (string)$orderHaocai, 2);
            $orderInfo->haocai_at = time();
        }
        if ($realHaocai == 0 && $orderInfo->is_haocai) {
            //已支付耗材费退费
            if (!empty($orderInfo->haocai_paid_at)) {
                $wechat->haocaiRefund($orderInfo->haocai_sn, $orderInfo->haocai_money);
            }
        }

        //续重补缴
        //如果订单重量不一致,并且订单信息的实际称重为空
        if ($result['calWeight'] != $orderInfo->weight && $result['typeCode'] != 99 && $result['feeOver'] == 1) {
            $calWeight = $result['calWeight'];
            //补差价
            //获取云洋渠道信息接口
            $data['channelTag'] = $orderInfo->channel_tag;
            $data['sender'] = $orderInfo->sender;
            $data['senderMobile'] = $orderInfo->sender_mobile;
            $data['senderProvince'] = $orderInfo->sender_province;
            $data['senderCity'] = $orderInfo->sender_city;
            $data['senderCounty'] = $orderInfo->sender_county;
            $data['senderTown'] = $orderInfo->sender_town;
            $data['senderLocation'] = $orderInfo->sender_location;
            $data['senderAddress'] = $orderInfo->sender_address;
            $data['receiver'] = $orderInfo->receiver;
            $data['receiverMobile'] = $orderInfo->receiver_mobile;
            $data['receiveProvince'] = $orderInfo->receive_province;
            $data['receiveCity'] = $orderInfo->receive_city;
            $data['receiveCounty'] = $orderInfo->receive_county;
            $data['receiveTown'] = $orderInfo->receive_town;
            $data['receiveLocation'] = $orderInfo->receive_location;
            $data['receiveAddress'] = $orderInfo->receive_address;
            $data['weight'] = $result['calWeight'];
            $data['packageCount'] = $orderInfo->package_count;

            if (empty($orderInfo->price_more)) {
                $json = (new YunyangService())->checkChannel($data);
                $arr = json_decode($json, true);
                $yunyang = $arr['result'];
                foreach ($yunyang as $k => $v) {
                    if ($v['channelId'] == $orderInfo->channel_id) {
                        if ($v['chargeType'] == 1) {
                            $priceOne = bcadd((string)$config['price_one'], $v['discountPriceOne']);
                            $priceMore = bcadd((string)$config['price_more'], $v['discountPriceMore']);
                        } else {
                            $priceOne = bcadd((string)$config['price_one'], (string)$v['priceOne'], 2);
                            $priceMore = bcadd((string)$config['price_more'], (string)$v['priceMore'], 2);
                        }
                    }

                }
            } else {
                $priceMore = $orderInfo->price_more;
            }


            if ($result['calWeight'] > $orderInfo->weight) {
                if ($priceMore != 0) {
                    $overWeight = ceil(bcsub($calWeight, $orderInfo->weight, 2));
                    $overWeightMoney = bcmul($priceMore, $overWeight, 2);
                    $orderInfo->is_overweight = 1;
                    $orderInfo->cal_weight = ceil($result['calWeight']);
                    $orderInfo->overweight_sn = uniqid();
                    $orderInfo->overweight_money = $overWeightMoney;
                    $orderInfo->overweight_at = time();
//                    //续重分销无效重新计算
//                    MembersProfit::where('order_id',$orderInfo->id)->where('type',4)->update(['status'=>2]);
//                    //首重续重分销计算
//                    $push['orderId'] = $orderInfo->id;
//                    $push['userId'] = $orderInfo->user_id;
//                    $push['useCoupon'] = !empty($orderInfo->coupon_id);
//                    $push['first'] = false;
//                    $push['more'] = true;
//                    $push['calWeight'] = $overWeight;
//                    $push['platform'] = $orderInfo->platform_id;
//                    MemberProfitTask::dispatch($push);
                    //小程序提醒超重
                    $message = [];
                    $message['thing1'] = ['value' => $orderInfo->tag_type];
                    $message['character_string2'] = ['value' => $orderInfo->waybill];
                    $message['number4'] = ['value' => $overWeight];
                    $message['amount5'] = ['value' => $overWeightMoney];
                    $message['thing6'] = ['value' => '请及时支付超重费用,以免影响寄件'];
                    $obj = (object)$message;

                    $page = 'pages/user/addMoney';
                    $wechat->sendMessage('rYgOcm2rCdA2ZVX-bufrhRkM2QYHxZ7NRURrqt2Pyjw', $userInfo->open_id, $obj, $page);
                }
            } elseif ($result['calWeight'] < $orderInfo->weight) {
                //重量小于实际重量退款
                $refundWeight = bcsub($orderInfo->weight, $calWeight);
                $refundMoney = bcmul($priceMore, $refundWeight, 2);
                $wechat->refundOrder($orderInfo->order_sn, $refundMoney);
                $orderInfo->is_overweight = 0;
                $orderInfo->overweight_money = 0;
                $orderInfo->cal_weight = ceil($result['calWeight']);
                $push['orderId'] = $orderInfo->id;
                $push['userId'] = $orderInfo->user_id;
                $push['useCoupon'] = !empty($orderInfo->coupon_id);
                $push['first'] = false;
                $push['more'] = true;
                $push['calWeight'] = $refundWeight;
                $push['platform'] = $orderInfo->platform_id;
                MemberProfitTask::dispatch($push);
            }


        }
        //补差价结束
        //订单已签收
        if ($result['typeCode'] == '3') {
            $orderInfo->type_code = $result['typeCode'];
            $orderInfo->status = 2;
            $orderInfo->type = $result['type'];
            //所有待入账订单进入到已入账
            $profitList = MembersProfit::where('order_id', $orderInfo->id)->get();
            foreach ($profitList as $v) {
                if ($v->status == 2) {
                    continue;
                }
                $v->status = 1;
                $money = $v->profit;
                if (Members::where('id', $v->user_id)->increment('price', $money)) {
                    $v->save();
                    //增加资金明细
                    //增加余额变动日志
                    $priceLog = [];
                    $priceLog = new MembersPriceLog();
                    $priceLog->user_id = $v->user_id;
                    $priceLog->money = $v->profit;
                    $priceLog->type = 2;
                    $priceLog->status = 1;
                    $priceLog->order_sn = $orderInfo->order_sn;
                    $priceLog->waybill = $result['waybill'];
                    $priceLog->save();
                }
            }
        }
        if ($result['typeCode'] == 99) {
            $orderInfo->is_overweight = 0;
            $orderInfo->is_haocai = 0;
            $orderInfo->status = 2;
            $wechat->refundOrder($orderInfo->order_sn, $orderInfo->money);
        }
        //订单签收结束
        $orderInfo->type_code = $result['typeCode'];
        $orderInfo->type = $result['type'];
        $orderInfo->volume = $result['volume'] ?? 0;
        if ($orderInfo->save()) {
            $return['code'] = 1;
            $return['message'] = '推送成功';
            return json($return);
        } else {
            $return['code'] = 0;
            $return['message'] = '推送失败';
            return json($return);
        }

    }


    //易达订单回调
    public function yidaCallback(Request $request)
    {
        $data['code'] = 200;
        $data['msg'] = '推送成功';
        $data['success'] = true;
        $post = $request->post();
        $model = new Yida();
        $model->json = json_encode($post);
        $model->save();
        YidaPushTask::dispatch($post);
        return json($data);
    }

    /**
     * @return string
     * 获取物流轨迹
     */
    public function getRoute(Request $request)
    {
        $data = $request->all();
        $waybill = $data['waybill'];
        $orderInfo = Orders::where('waybill', $waybill)->first();
        if ($orderInfo->channel_type == 'yida') {
            $json = (new YidaService)->getRoute($data);
            $list = json_decode($json, true);
            $route = $list['data'];
            $return['code'] = 1;
            $return['message'] = '获取成功';
            $return['result'] = $route;
            return json($return);
        } else {
            return (new YunyangService)->getRoute($data);
        }

    }


    /**
     * 更新用户
     *
     * @urlParam id int required 用户ID
     *
     * @bodyParam Member string required 用户名
     * @bodyParam password string 密码
     * @bodyParam email string 邮箱
     * @bodyParam mobile string 手机号
     * @bodyParam department_id int 部门
     * @bodyParam roles integer[] 角色
     * @bodyParam jobs integer[] 职位
     *
     * @responseField data bool 是否更新成功
     *
     * @param $id
     * @param Request $request
     * @return mixed
     */
    public function update($id, Request $request): mixed
    {
        if ($this->order->where('id', $id)->update($request->all())) {
            return $this->success('修改成功');
        } else {
            return $this->fail('修改失败');
        }

    }

    /**
     * 删除用户
     *
     * @responseField data bool 是否更新成功
     *
     * @return Response
     */
    public function destroy($id)
    {
        if ($this->order->where('id', $id)->delete()) {
            return $this->success('删除成功');
        } else {
            return $this->fail('删除失败');
        }
    }

    /**
     * @param Request $request
     * @return Response
     * 团队订单
     */
    public function teamOrder(Request $request)
    {
        $search = $request->get('search');
        $status = $request->get('status');
        $isCityAgent = $request->get('is_city_agent') ?? 0;
        $endOfDay = Carbon::today()->endOfDay()->timestamp;
        $startOfDay = $endOfDay - 60 * 86400;
        $teamCache = Redis::hget($this->getLoginUserId(), 'team');
        $teamArr = explode(",", $teamCache);
        $teamArr[] = $this->getLoginUserId();
        $startTime = $request->get('start_time');
        $endTime = $request->get('end_time');


        $today = [
            Carbon::now()->startOfDay()->timestamp,
            Carbon::now()->endOfDay()->timestamp
        ];
        $every = [
            strtotime($startTime . "00:00:00"),
            strtotime($endTime . "23:59:59")
        ];

        $temp = $this->order::with('user')->select(['waybill', 'item_name', 'paid_at', 'money', 'type_code', 'status', 'id', 'user_id', 'tag_type', 'type', 'is_overweight', 'overweight_paid_at','sender_city','created_at',
            'updated_at']);
        if (!empty($isCityAgent)) {
            $userId = $this->getLoginUserId();
            $userInfo = Members::find($userId);
            $agentCityName = $userInfo->agent_city_name;
            $temp = $temp->whereLike('sender_city', $agentCityName . '%')->where('created_at', '>', $userInfo->agent_start_at);
        } else {
            if (!empty($search)) {
                $temp = $temp->where(function ($query) use ($search) {
                    return $query->where('user_id', $search)
                        ->orWhere('receiver_mobile', $search)
                        ->orWhere('waybill', $search);
                });
            } else {

                $temp = $temp->whereIn('user_id', function ($query) use ($teamArr) {
                    return $query->from('members')->whereIn('id', $teamArr)->select(['id'])->get();
                });
            }
        }


        if (!empty($startTime) && !empty($endTime)) {
            $temp = $temp->whereBetween('updated_at', $every);
        }

        if ($status == '0') {
            $temp = $temp->where(function ($query) {
                $query->whereNull('type_code')
                    ->orWhereIn('type_code', [1, 2]);
            });
        } elseif ($status == '1') {
            $temp = $temp->where('type_code', 3);
        } elseif ($status == '2') {
            $temp = $temp->whereIn('type_code', [4, 5, 99]);
        } else {
            $temp = $temp->whereIn('type_code', [1, 2, 3]);
        }
        $list = $temp->orderBy('created_at', 'desc')->paginate(10)->toArray();
        if ($isCityAgent) {
            foreach ($list['data'] as $k => $v) {
                if (empty($list['data'][$k]['user'])) {
                    $list['data'][$k]['user'] = [
                        'id' => 1,
                        'avatar' => 'https://xingjukuaidi.oss-cn-beijing.aliyuncs.com/image/avatar.png',
                        'username' => '微信用户'
                    ];
                }
                $query = MembersProfit::where('user_id', $this->getLoginUserId())->where('order_id', $v['id']);
                $profit = $query->where('type', 3)->value('profit');
                $list['data'][$k]['profit'] = $profit ?? 0;
            }
            $data['list'] = $list;
        } else {
            $newArr = [];
            foreach ($list['data'] as $k => $v) {
                if (empty($v['user'])) {
                    $v['user'] = [
                        'id' => 1,
                        'avatar' => 'https://xingjukuaidi.oss-cn-beijing.aliyuncs.com/image/avatar.png',
                        'username' => '微信用户'
                    ];
                }
                $profitList = MembersProfit::where('user_id', $this->getLoginUserId())->where('order_id', $v['id'])->whereIn('type', [1, 2, 4, 5])->orderBy('id', 'desc')->get();
                if (count($profitList) == 0) {

                    $v['profit'] = 0;
                    $v['profit_type'] = 1;
                    $profitStatus = match ($v['type_code']) {
                        '0', '1', '2' => 0,
                        '3' => 1,
                        default => 2,
                    };
                    $v['status'] = $profitStatus;
                    $newArr[] = $v;
                } else {
                    foreach ($profitList as $k1 => $profitInfo) {
                        $v['profit'] = $profitInfo->profit;
                        $v['profit_type'] = $profitInfo->type;
                        $v['status'] = $profitInfo->status;
                        $newArr[] = $v;
                    }
                }

            }
            $list['data'] = $newArr;
            $data['list'] = $list;
        }


        $temp2 = $this->order;
        if (!empty($startTime) && !empty($endTime)) {
            $temp2 = $temp2->whereBetween('updated_at', $every);
        }

        if ($status == '0') {
            $temp2 = $temp2->where(function ($query) {
                $query->whereNull('type_code')
                    ->orWhereIn('type_code', [1, 2]);
            });
        } elseif ($status == '1') {
            $temp2 = $temp2->where('type_code', 3);
        } elseif ($status == '2') {
            $temp2 = $temp2->whereIn('type_code', [4, 5, 99]);
        } else {
            $temp2 = $temp2->whereIn('type_code', [1, 2, 3]);
        }
        if ($isCityAgent) {
            $data['count'] = $temp2->whereLike('sender_city', $userInfo->agent_city_name . '%')->where('created_at', '>', $userInfo->agent_start_at)->whereBetween('created_at', [$startOfDay, $endOfDay])->count();
        } else {
            $data['count'] = $temp2->whereIn('user_id', function ($query) use ($teamArr) {
                $query->from('members')->whereIn('id', $teamArr)->select(['id'])->get();
            })->count();
        }

        $query = MembersProfit::where('user_id', $this->getLoginUserId());
        if ($isCityAgent) {
            $query = $query->where('type', 3)->where('created_at', '>', $userInfo->agent_start_at);
        } else {
            $query = $query->whereIn('type', [1, 4]);
        }
        if (is_numeric($status)) {
            $query = $query->where('status', $status);

        } else {
            $query = $query->whereIn('status', [0, 1]);
        }
        if ($isCityAgent) {
            $data['sum'] = $query->sum('profit');
        } else {
            $add = $query->sum('profit');
            $backQuery = MembersProfit::where('user_id', $this->getLoginUserId())->where('type', 5);  //退款
            if (is_numeric($status)) {
                $backQuery = $backQuery->where('status', $status);
            }
            $back = $backQuery->sum('profit');
            $data['sum'] = bcsub($add, $back, 2);
        }
        return $this->data($data);
    }


    public function overweightOrder(Request $request)
    {
        $waybill = $request->get('waybill', '');
        $status = $request->get('status', '2');
        $where = [];
        if (!empty($waybill)) {
            $arr = explode(",", $waybill);
            $where[] = ['waybill', 'in', $arr];
        }

        $query = $this->order->where($where);
        if ($status == 1) {
            $query = $query->where(function ($query) {
                $query->where('overweight_paid_at', '>', 0)->orWhere('haocai_paid_at', '>', 0);
            });
        } elseif ($status == 2) {
            $query = $query->where(function ($query) {
                $query->where('overweight_paid_at', 0)->where('is_overweight', 1)->orwhere(function ($query) {
                    $query->where('haocai_paid_at',0)->where('is_haocai',1);
                });
            });
        }
        $orderList = $query->where(function ($query) {
            $query->where('is_overweight', 1)->orWhere('is_haocai', 1);
        })->where('user_id', $this->getLoginUserId())->orderBy('id', 'desc')
            ->select(['id', 'waybill', 'channel_logo_url', 'tag_type', 'weight', 'cal_weight', 'item_name', 'overweight_money', 'overweight_sn', 'is_overweight',
                'haocai_money', 'haocai_sn', 'is_haocai'])->paginate(10)->toArray();
        if (!empty($orderList['data'])) {

            $newArr = [];

            foreach ($orderList['data'] as $k => $v) {
                if ($v['is_overweight'] == 1) {
                    $v['order_type'] = 1;
                    $newArr[] = $v;
                }
                if ($v['is_haocai'] == 1) {
                    $v['order_type'] = 2;
                    $newArr[] = $v;
                }
            }
            $orderList['data'] = $newArr;
        }
        return $this->data($orderList);
    }

    public function RefundRecord(Request $request)
    {
        $waybill = $request->get('waybill', '');
        $where = [];
        if (!empty($waybill)) {
            $arr = explode(",", $waybill);
            $where[] = ['waybill', 'in', $arr];
        }

        $orderList = RefundRecord::with('order')->where($where)->where('user_id', $this->getLoginUserId())->orderBy('id', 'desc')->paginate(10);
        if (!empty($orderList)) {
            foreach ($orderList as $k => $v) {
                $orderList[$k]->weight = $v->order->weight;
                $orderList[$k]->waybill = $v->order->waybill;
                $orderList[$k]->cal_weight = $v->order->cal_weight;
                $orderList[$k]->refund_weight = abs(bcsub((string)$v->order->weight, (string)$v->order->cal_weight));
                $orderList[$k]->item_name = $v->order->item_name;
                $orderList[$k]->refund_money = $v->refund_money;
            }
        }
        return $this->data($orderList->toArray());
    }

    public function test(Request $request)
    {
        $orderId = $request->post('order_id');
        $orderInfo = Orders::find($orderId);
        $orderSn = $orderInfo->order_sn;
        if (!empty($orderInfo)) {
            $data = [];
            $data['channelTag'] = $orderInfo->channel_tag;  //快递中文名称
            $data['channelId'] = $orderInfo->channel_id;  //快递中文名称
            $data['tag_type'] = $orderInfo->tag_type;  //快递中文名称
            $data['sender'] = $orderInfo->sender;
            $data['senderMobile'] = $orderInfo->sender_mobile;
            $data['senderProvince'] = $orderInfo->sender_province;
            $data['senderCity'] = $orderInfo->sender_city;
            $data['senderCounty'] = $orderInfo->sender_county;
//            $data['senderTown'] = $orderInfo->sender_town;
            $data['senderLocation'] = $orderInfo->sender_location;
            $data['senderAddress'] = $orderInfo->sender_address;
            $data['receiver'] = $orderInfo->receiver;
            $data['receiverMobile'] = $orderInfo->receiver_mobile;
            $data['receiveProvince'] = $orderInfo->receive_province;
            $data['receiveCity'] = $orderInfo->receive_city;
//            $data['receiveTown'] = $orderInfo->receive_town;
            $data['receiveCounty'] = $orderInfo->receive_county;
            $data['receiveLocation'] = $orderInfo->receive_location;
            $data['receiveAddress'] = $orderInfo->receive_address;
            $data['weight'] = $orderInfo->weight;
            $data['itemName'] = $orderInfo->item_name;  //物品名称
            $data['packageCount'] = (int)$orderInfo->package_count; //包裹数量
            $data['billRemark'] = $orderInfo->bill_remark; //订单备注
            $data['insured'] = $orderInfo->insured ?? 0; //订单备注
            //未付款才可以回调
            if ($orderInfo->status == 0) {
                $orderInfo->status = 1;
                $orderInfo->paid_at = time();
                if ($orderInfo->channel_type == 'yida') {
                    //易达下单
                    $data['deliveryType'] = $orderInfo->tag_str;
                    $data['thirdNo'] = $orderInfo->order_sn;
                    $json = (new YidaService)->createOrder($data);
                    $result = json_decode($json, true);
                    if ($result['code'] == 200) {
                        return $this->success('易达下单成功');
                    }
                } else {
                    //云洋下单
                    $json = (new YunyangService)->createOrder($data);
                    $result = json_decode($json, true);
                    if ($result['code'] == 1) {
                        AddPostmanInfo::dispatch($orderInfo->id, 1);
                        $result2 = $result['result'];
                        $orderInfo->platform_id = $result2['billType'];
                        $orderInfo->waybill = $result2['waybill'];
                        $orderInfo->type = $result2['type'];
                        $orderInfo->type_code = $result2['typeCode'];
                        $orderInfo->save();

                        //用户下单数量+1
                        Members::where('id', $orderInfo->user_id)->increment('over_count');
                        //延时获取快递员信息

                        //返佣以及记录
                        $userId = $orderInfo->user_id;
                        if (!empty($orderInfo->coupon_id)) {
                            $useCoupon = true;
                        } else {
                            $useCoupon = false;
                        }

                    } else {
                        $orderInfo->type = '地址有误';
                        $orderInfo->save();
                        $this->refundOrder($orderSn, $orderInfo->money);
                    }
                }

            }
        } else {
            //快递补缴
            $orderInfo = Orders::where('overweight_sn', $orderSn)->first();
            $orderInfo->overweight_paid_at = time();
            $orderInfo->save();
        }

    }

    /**
     * @return void
     * 订单关闭
     */
    public function closeOrder()
    {
        $time = time() - 1800;
        $list = $this->order->where('created_at', '<', $time)->where('paid_at', null)->get();
        foreach ($list as $v) {
            $orderId = $v->id;
            $v->status = 2;
            $v->type = '已关闭';
            $v->type_code = 99;
            $v->save();
            MembersProfit::where('order_id', $orderId)->update(['status' => 2]);
        }

    }
}

